﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using InHD.model;
using System.Reflection;
using System.Data;
using InHD.utilities;

namespace InHD.dataaccess
{
    class SupplierRepository
    {
        #region Fields
        List<Supplier> _suppliers;
        //For DB Utils
        private DBUltils _db;
        string[] _paramName;
        string[] _value;
        DBUltils.ParamType[] _paramType;
        #endregion // Fields

        #region Constructor

        /// <summary>
        /// Creates a new repository of CompanyInfos.
        /// </summary>
        public SupplierRepository()
        {
            _suppliers = new List<Supplier>();
            this._db = new DBUltils();
            if (!_db.connectDB(Constants.Security.DefaultDBUser, Constants.Security.DefaultDBPassword))
                throw new ArgumentNullException(Constants.Messages.CannotConnectDB);
        }

        #endregion // Constructor

        #region Public Interface

        public event EventHandler<SupplierAddedEventArgs> SupplierAdded;

        public string AddSupplier(Supplier supplier)
        {
            try
            {
                if (supplier == null)
                    throw new ArgumentNullException("product");
                for (int i = 0; i < this._suppliers.Count; i++)
                {
                    if (this._suppliers[i].SupplierCode.Equals(supplier.SupplierCode))
                    {
                        return "DuplicateCode";
                    }
                }
                supplier.SupplierUNK = "Sup-" + Guid.NewGuid().ToString();

                //// Add new product into database
                if (_db == null)
                    throw new ArgumentNullException(Constants.Messages.DBNotInitialized);
                if (supplier.SupplierUNK == null)
                    throw new ArgumentNullException("Null Unique key");
                _paramName = new string[]{"@supplierUNK",
                                        "@name",
                                        "@contact",
                                        "@address",
                                        "@email",
                                        "@phone",
                                        "fax",
                                        "@supplierCode",
                                        "@deliverDelay",
                                        "@freeDelivery"
            };
                _paramType = new DBUltils.ParamType[]{DBUltils.ParamType.Str,
                                                    DBUltils.ParamType.NStr,
                                                    DBUltils.ParamType.NStr,
                                                    DBUltils.ParamType.LNStr,
                                                    DBUltils.ParamType.Str,
                                                    DBUltils.ParamType.Str,
                                                    DBUltils.ParamType.Str,
                                                    DBUltils.ParamType.Str,
                                                    DBUltils.ParamType.Int,
                                                    DBUltils.ParamType.Int
                                                    };
                _value = new string[]{supplier.SupplierUNK,
                                    supplier.Name,
                                    (supplier.Contact == null) ? string.Empty : supplier.Contact,
                                    (supplier.Address == null) ? string.Empty : supplier.Address,
                                    (supplier.Email == null) ? string.Empty : supplier.Email,
                                    (supplier.Phone == null) ? string.Empty : supplier.Phone,
                                    (supplier.Fax == null) ? string.Empty : supplier.Fax,
                                    supplier.SupplierCode,
                                    supplier.DeliveryDelay.ToString(),
                                    (supplier.FreeDelivery) ? "1" : "0"
                                    };

                _db.queryDB("AddSupplier", _paramName, _paramType, _value, DBUltils.QueryType.Insert);
                _suppliers.Add(supplier);

                if (this.SupplierAdded != null)
                    this.SupplierAdded(this, new SupplierAddedEventArgs(supplier));
            }
            catch (Exception e)
            {
                Logger.RecordMessage(e, MessageType.Error);
                return e.Message;
            }
            //System.Windows.MessageBox.Show("Add supplier successfully!!!");
            return string.Empty;
        }

        public string EditSupplier(Supplier supplier)
        {
            try
            {
                if (supplier == null)
                    throw new ArgumentNullException("supplier");

                //// edit existing product which have productUNK  == product.ProductUNK
                for (int i = 0; i < this._suppliers.Count; i++)
                {
                    if (this._suppliers[i].SupplierUNK.Equals(supplier.SupplierUNK))
                    {
                        for (int j = 0; j < this._suppliers.Count; j++)
                        {
                            if ((i != j) && this._suppliers[j].SupplierCode.Equals(supplier.SupplierCode))
                            {
                                return "DuplicateCode";
                            }
                        }
                        this._suppliers[i] = supplier;
                        if (_db == null)
                            throw new ArgumentNullException(Constants.Messages.DBNotInitialized);
                        _paramName = new string[]{"@supplierUNK",
                                        "@name",
                                        "@contact",
                                        "@address",
                                        "@email",
                                        "@phone",
                                        "fax",
                                        "@supplierCode",
                                        "@deliverDelay",
                                        "@freeDelivery"
            };
                        _paramType = new DBUltils.ParamType[]{DBUltils.ParamType.Str,
                                                    DBUltils.ParamType.NStr,
                                                    DBUltils.ParamType.NStr,
                                                    DBUltils.ParamType.LNStr,
                                                    DBUltils.ParamType.Str,
                                                    DBUltils.ParamType.Str,
                                                    DBUltils.ParamType.Str,
                                                    DBUltils.ParamType.Str,
                                                    DBUltils.ParamType.Int,
                                                    DBUltils.ParamType.Int
                                                    };
                        _value = new string[]{supplier.SupplierUNK,
                                    supplier.Name,
                                    (supplier.Contact == null) ? string.Empty : supplier.Contact,
                                    (supplier.Address == null) ? string.Empty : supplier.Address,
                                    (supplier.Email == null) ? string.Empty : supplier.Email,
                                    (supplier.Phone == null) ? string.Empty : supplier.Phone,
                                    (supplier.Fax == null) ? string.Empty : supplier.Fax,
                                    supplier.SupplierCode,
                                    supplier.DeliveryDelay.ToString(),
                                    (supplier.FreeDelivery) ? "1" : "0"
                                    };

                        _db.queryDB("UpdateSupplier", _paramName, _paramType, _value, DBUltils.QueryType.Update);
                        break;
                    }
                }
            }
            catch (Exception e)
            {
                Logger.RecordMessage(e, MessageType.Error);
                return e.Message;
            }
            //System.Windows.MessageBox.Show("Edit supplier successfully!!!");
            return string.Empty;
        }

        public string DeleteSupplier(string UNK)
        {
            bool found = false;
            foreach (Supplier supplier in this._suppliers)
            {
                if (supplier.SupplierUNK.Equals(UNK))
                {
                    this._suppliers.Remove(supplier);
                    found = true;
                    break;
                }
            }
            if (!found)
                return "UNK is not exist";
            try
            {
                if (_db == null)
                    throw new ArgumentNullException(Constants.Messages.DBNotInitialized);
                if (UNK == null)
                    throw new ArgumentNullException("Null Unique key");
                _paramName = new string[] { "@supplierUNK" };
                _paramType = new DBUltils.ParamType[] { DBUltils.ParamType.Str };
                _value = new string[] { UNK };

                _db.queryDB("DeleteSupplier", _paramName, _paramType, _value, DBUltils.QueryType.Delete);
            }
            catch (Exception e)
            {
                Logger.RecordMessage(e, MessageType.Error);
                return e.Message;
            }
            //System.Windows.MessageBox.Show("Delete Supplier successfully!!!");
            return string.Empty;
        }

        public List<Supplier> GetSuppliers()
        {
            return this._suppliers;
        }

        public List<Supplier> GetSuppliersWthSearchCriteria(string property, string criteria)
        {
            List<Supplier> tmpList = new List<Supplier>();
            foreach (Supplier pro in this._suppliers)
            {
                Type t = pro.GetType();
                PropertyInfo p = t.GetProperty(property);
                string valueOfProperty = (string)p.GetValue(pro, null);
                if (valueOfProperty.ToUpper().Contains(string.IsNullOrEmpty(criteria) ? string.Empty : criteria.ToUpper()))
                {
                    tmpList.Add(pro);
                }
            }

            return tmpList;
        }

        public string LoadAllSuppliers()
        {
            try
            {
                if (_db == null)
                    throw new ArgumentNullException(Constants.Messages.DBNotInitialized);
                _paramName = new string[] { };
                _paramType = new DBUltils.ParamType[] { };
                _value = new string[] { };
                DataSet ds = _db.queryDB("GetAllSupplier", _paramName, _paramType, _value, DBUltils.QueryType.Select);

                foreach (DataRow r in ds.Tables[0].Rows)
                {
                    Supplier supplier = Supplier.CreateSupplierInfo(Convert.ToString(r["supplierCode"]),
                                                    Convert.ToString(r["name"]),
                                                    Convert.ToInt32(r["deliverDelay"]),
                                                    Convert.ToBoolean(r["freeDelivery"]),
                                                    Convert.ToString(r["contact"]),
                                                    Convert.ToString(r["phone"]),
                                                    Convert.ToString(r["fax"]),
                                                    Convert.ToString(r["email"]),
                                                    Convert.ToString(r["address"]),
                                                    Convert.ToString(r["supplierUNK"]));
                    this._suppliers.Add(supplier);
                }
            }
            catch (Exception e)
            {
                Logger.RecordMessage(e, MessageType.Error);
                return e.Message;
            }
            return string.Empty;
        }

        public DataTable GetProductBySupplier(string supUNK)
        {
            DataSet ds;
            DataTable dt = new DataTable();
            if (_db == null)
                return dt;
            if (supUNK == null)
                return dt;
            _paramName = new string[] { "@supplierUNK" };
            _paramType = new DBUltils.ParamType[] { DBUltils.ParamType.Str };
            _value = new string[] { supUNK };

            ds = _db.queryDB("GetProductBySupplier", _paramName, _paramType, _value, DBUltils.QueryType.Select);
            return ds.Tables[0];
        }

        public DataTable GetReceivedBySupplier(string supUNK)
        {
            DataSet ds;
            DataTable dt = new DataTable();
            if (_db == null)
                return dt;
            if (supUNK == null)
                return dt;
            _paramName = new string[] { "@supUNK" };
            _paramType = new DBUltils.ParamType[] { DBUltils.ParamType.Str };
            _value = new string[] { supUNK };

            ds = _db.queryDB("GetProductBySupplier", _paramName, _paramType, _value, DBUltils.QueryType.Select);
            return ds.Tables[0];
        }

        public DataTable GetReturnedBySupplier(string supUNK)
        {
            DataSet ds;
            DataTable dt = new DataTable();
            if (_db == null)
                return dt;
            if (supUNK == null)
                return dt;
            _paramName = new string[] { "@supUNK" };
            _paramType = new DBUltils.ParamType[] { DBUltils.ParamType.Str };
            _value = new string[] { supUNK };

            ds = _db.queryDB("GetReturnedBySupplier", _paramName, _paramType, _value, DBUltils.QueryType.Select);
            return ds.Tables[0];
        }
        #endregion // Public Interface       
    }
}
